declare interface Window {
  $: (selector: string) => JQuery
}
class JQuery {
  selector: string
  length: number
  constructor(selector: string) {
    // 使用 slice 因为 NodeList 不是数组，没有数组的方法
    const domList = Array.prototype.slice.call(document.querySelectorAll(selector))
    const length = domList.length // 获取长度
    for (let i = 0; i < length; i++) {
      this[i] = domList[0]
    }
    this.selector = selector
    this.length = length
  }

  append(elem: HTMLElement): JQuery {
    // ...
    return this
  }

  addClass(key: string, value: string): JQuery {
    // ...
    return this
  }
}

/**
 * 工厂模式：
 * 如果开放给用户的不是`$`，而是`new JQuery(selector)`，
 * 带来的问题：
 * 不方便链式操作；
 * 不宜将构造函数暴露给用户
 * 尽量高内聚、低耦合；
 */
window.$ = selector => {
  return new JQuery(selector)
}
